package org.etherframework.tests.features.mediation
{
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	
	import org.etherframework.IEther;
	import org.etherframework.core.IModule;
	import org.etherframework.dependency.IDependencies;
	import org.etherframework.mediation.Mediations;
	import org.etherframework.tests.features.mediation.models.SampleModel;
	import org.etherframework.tests.features.mediation.providers.SampleProvider;
	import org.etherframework.tests.utils.ModuleInfo;
	import org.etherframework.tests.utils.TestUtility;
	import org.flexunit.async.Async;
	import org.fluint.uiImpersonation.UIImpersonator;
	import org.hamcrest.assertThat;
	import org.hamcrest.collection.emptyArray;
	import org.hamcrest.object.equalTo;
	import org.hamcrest.object.nullValue;
	
	import spark.components.Group;

	public class when_using_contextual_unbind
	{	
		private static var _testUtility:TestUtility = new TestUtility();
		private static var _info:ModuleInfo;
		private static var _context:IModule;
		private static var _d:IDependencies;
		private static var _ether:IEther;
		private static var _moduleView:Group;
		
		[BeforeClass(async)]
		public static function setUpBeforeClass():void
		{
			_moduleView = UIImpersonator.addChild(new Group()) as Group;
			_info = _testUtility.createModuleInfo(null, _moduleView);
			_context = _info.module;
			_d = _info.module.dependencies;
			_ether = _info.module.ether;
			
			_d.addClass(SampleModel);
			_d.addClass(SampleProvider);
			
			const dispatcher:IEventDispatcher = Mediations.prepare([SampleModel, SampleProvider]);
			Async.proceedOnEvent(when_using_contextual_unbind, dispatcher, Event.COMPLETE, 10000);
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
			_testUtility.dispose();
			UIImpersonator.removeAllChildren();
		}
		
		
		[Test(order=1)]
		public function it_should_not_execute_setter_handler():void
		{
			//Arrange
			var value:String = "foo";
			var executedValue:String
			var model:SampleModel = _ether.dependencies.getInstance(SampleModel) as SampleModel;
			var handler:Function = function(value:String):void{ executedValue = value; };
			
			_ether.mediations.contextual("123").bind.property(model.currentItem, handler);
			_ether.mediations.contextual("123").unbind.property(model.currentItem, handler);
			
			// Act
			_ether.mediations.contextual("123").execute.binding(model.currentItem = value);
			
			// Assert
			assertThat(executedValue, nullValue());
		}
		
		[Test(order=2)]
		public function it_should_not_execute_getter_handler():void
		{
			//Arrange
			var substitutedValue:String;
			var model:SampleModel = _ether.dependencies.getInstance(SampleModel) as SampleModel;
			var handler:Function = function():String{ return "foo"; };
			
			model.currentItem = "bar";
			_ether.mediations.contextual("321").bind.property(model.currentItem, null, handler);
			_ether.mediations.contextual("321").unbind.property(model.currentItem, null, handler);

			// Act
			_ether.mediations.contextual("321").execute.binding(substitutedValue = model.currentItem);
			
			// Assert
			assertThat(substitutedValue, equalTo("bar"));
		}
		
		
		[Test(order=3)]
		public function it_should_not_execute_method_handler():void
		{
			//Arrange
			var executedValue:Array = [];
			var provider:SampleProvider = _ether.dependencies.getInstance(SampleProvider) as SampleProvider;
			var handler:Function = function(value:String):void{ executedValue.push(value); };
			
			_ether.mediations.contextual("77").bind.method(provider.updateSomethig(null), handler);
			_ether.mediations.contextual("77").unbind.method(provider.updateSomethig(null), handler);
			
			// Act
			_ether.mediations.contextual("77").execute.binding(provider.updateSomethig("red"));
			
			// Assert
			assertThat(executedValue, emptyArray());
		}
		
		[Test(order=4)]
		public function it_should_not_execute_method_handler_with_result():void
		{
			//Arrange
			var returnValue:String;
			var substitutedValue:String;
			var provider:SampleProvider = _ether.dependencies.getInstance(SampleProvider) as SampleProvider;
			var handler:Function = function():String{ return "anotherData"; };
			
			_ether.mediations.contextual("8").bind.method(provider.getCurentData(), handler);
			_ether.mediations.contextual("8").unbind.method(provider.getCurentData(), handler);
			
			// Act
			_ether.mediations.contextual("8").execute.binding(substitutedValue = provider.getCurentData());
			
			// Assert
			assertThat(substitutedValue, equalTo("currentData"));
		}
	}
}